home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Alles Voor Internet / Tout Pour Internet
/
alles voor internet.iso
/
MacInternet™
/
Telnet
/
NCSA
/
tn3270 2.3d26 source
/
tn3270
/
writetm.c
< prev
Wrap
Text File
|
1991-04-08
|
14KB
|
669 lines
/*
* tn3270 for the Macintosh Source Code
* Brown University Computing and Information Services
* Version 2.3d21, January 17, 1991
* Copyright (c) 1988, 1989, 1990, 1991 by Brown University and by
* Peter John DiCamillo.
*
* Permission is granted to any individual or institution to use, copy,
* or redistribute the binary version of this software and its
* documentation provided this notice and the copyright notices are
* retained. Permission is granted to any individual or non-profit
* institution to use, copy, modify, or redistribute the source files
* of this software provided this notice and the copyright notices are
* retained. This software may not be distributed for profit, either
* in original form or in derivative works, nor can the source be
* distributed to other than an individual or a non-profit institution.
* Any individual or group interested in seeing and/or using these
* source files but who are prevented from doing so by the above
* constraints should contact Don Wolfe, Assistant Vice-President for
* Computer Systems at Brown University, (401) 863-7250, for possible
* software licensing of the source developed at Brown.
*
* Brown University and Peter John DiCamillo make no representations
* about the suitability of this software for any purpose.
*
* BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
* EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
* INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#define __SEG__ 3270seg1
#include "maclib.h"
#include "termdef.h"
#include "globals.h"
extern unsigned char ordertab[];
extern short maxoff, maxcnt, scrhsize;
char colorfield = 0;
extern Rect selrect; /* rectangle for last text selection */
static short attrloc = 0; /* location where last attribute was stored */
char skipnewmode; /* skip call to newmode for EW/EWA */
writetm(cmd, len, init)
unsigned char * cmd;
short len;
char init;
{
register short left;
register short size;
register unsigned char c, ew;
if (init) {
ew = 0; /* erase/write flag */
if ((cmd[0] & 0x07) >= 5) { /* interpret op-code */
ew = 1;
if (skipnewmode == 0) {
if (((cmd[0] & 0x0f) == 0x0d) || (cmd[0] == 0x7e)) { /* ewa */
ewamode = 1;
}
else { /* possible end of ewa */
ewamode = 0;
}
newmode(ewamode, 0);
}
clrscn();
}
intwcc(ew, cmd[1]); /* interpret WCC */
ldvoff = 2; /* skip to start of data */
ptfill = 0;
chratr = 0;
bufadr = curadr; /* buffer address starts out at cursor */
}
while (ldvoff < len) {
/* special code to handle data quickly */
c = cmd[ldvoff++];
if (ordertab[c]) {
chrbuff[bufadr] = c;
atrbuff[bufadr] = chratr;
if ((c == 0xad) || (c == 0xbd))
if (fixbracket) atrbuff[bufadr] += 0x4000;
bufadr++;
if (bufadr == maxcnt) bufadr = 0;
ptfill = 1;
continue;
}
else ldvoff--;
/* order processing code */
left = len - ldvoff;
switch(cmd[ldvoff]) {
case 0x1D: /* Start Field */
if (left < 2) return;
intsf(cmd[ldvoff+1]);
ldvoff += 2;
ptfill = 0;
break;
case 0x11: /* Set Buffer Address */
if (left < 3) return;
intsba(cmd[ldvoff+1], cmd[ldvoff+2]);
ldvoff += 3;
ptfill = 0;
break;
case 0x13: /* Insert Cursor */
intic();
ldvoff++;
ptfill = 0;
break;
case 0x05: /* Program Tab */
intpt();
ldvoff++;
break;
case 0x3C: /* Repeat to Address */
if (left < 4) return;
c = cmd[ldvoff+3];
if (c == 0x08) {
if (left < 5) return;
c = cmd[ldvoff+4];
intra(cmd[ldvoff+1], cmd[ldvoff+2], c, 1);
ldvoff += 5;
}
else {
intra(cmd[ldvoff+1], cmd[ldvoff+2], c, 0);
ldvoff += 4;
}
ptfill = 0;
break;
case 0x12: /* Erase Unprotected to Address */
if (left < 3) return;
inteua(cmd[ldvoff+1], cmd[ldvoff+2]);
ldvoff += 3;
ptfill = 0;
break;
case 0x08: /* Graphics Escape */
if (left < 2) return;
intdata(cmd[ldvoff+1], 1);
ldvoff += 2;
break;
case 0x29: /* Start Field Extended */
if (left < 2) return;
size = (cmd[ldvoff+1]+1) * 2;
if (left < size) return;
intsfe(cmd+ldvoff+2, cmd[ldvoff+1]);
ldvoff += size;
ptfill = 0;
break;
case 0x2C: /* Modify Field */
if (left < 2) return;
size = (cmd[ldvoff+1]+1) * 2;
if (left < size) return;
intmf(cmd+ldvoff+2, cmd[ldvoff+1]);
ldvoff += size;
ptfill = 0;
break;
case 0x28: /* Set Attribute */
if (left < 3) return;
intsa(cmd[ldvoff+1], cmd[ldvoff+2]);
ldvoff += 3;
ptfill = 0;
break;
default: /* shouldn't happen */
break;
}
}
}
clrscn()
{
setmem(chrbuff, maxcnt, 0);
setmem(atrbuff, maxcnt<<1, 0);
curadr = 0;
bufadr = 0;
colorfield = 0;
textsel = 0;
fmtscrn = 0;
}
intwcc(ew, wcc)
unsigned char ew, wcc;
{
register short i;
register char code;
lastwcc = wcc & 0x7f;
if (wcc & 0x01) for (i=0; i < maxcnt; i++) {
atrbuff[i] &= 0xFEFF;
}
kb_err = 0;
if (kblock) {
lastwcc |= 0x80; /* remember was locked */
/* indicate SYSTEM immediately */
if ((kblcode == 2) && ((wcc & 0x02) == 0)) {
kblcode = 1;
if (!int_active) newstat();
}
}
else {
kblock = 1;
kblcode = 2;
if (!int_active) newstat();
}
if (ew) if (wcc & 0x40) /* wcc reset in EW/EWA */
if (!int_active) clrpict(); /* erase graphics */
else pndclr = 1;
}
endwcc()
{
if (lastwcc & 0x04) if (!(int_active || tcpflg)) beep();
else pndbeep = 1;
if (lastwcc & 0x02) rdaid = 0x60; /* reset last AID */
if (cs.curpos) {
x = curadr%scrhsize;
y = curadr/scrhsize;
}
if ((lastwcc & 0x82) != 0x80) {
kblock = 0;
kblcode = 0;
if (!int_active) newstat();
}
else if (cs.curpos) if (!int_active) newstat();
checkfmt(); /* check that fmtscrn is still correct */
}
checkfmt() /* check all attributes have not been overwritten by data */
{
register short i;
/* unformatted is always correct */
if (fmtscrn == 0) return;
/* formatted if attribute where we last put one */
if (atrbuff[attrloc] & 0x8000) return;
/* else look for an attribute byte */
for (i=0; i < maxcnt; i++)
if (atrbuff[i] & 0x8000) return;
/* all attributes were overwritten: reset flag */
fmtscrn = 0;
}
intsf(attr)
unsigned char attr;
{
chrbuff[bufadr] = 0x1d;
atrbuff[bufadr] = 0x8000 + ((attr & 0x3f) << 8);
attrloc = bufadr;
bufadr++;
if (bufadr == maxcnt) bufadr = 0;
fmtscrn = 1;
}
intsba(a1, a2)
unsigned char a1, a2;
{
bufadr = cvtadr(a1, a2);
}
intic()
{
curadr = bufadr;
}
intpt()
{
register unsigned short a;
while (true) { /* loop through protected fields */
while (!(atrbuff[bufadr] & 0x8000)) { /* get to next attribute */
if (ptfill) setnull(); /* fill with nulls if set */
else {
bufadr++;
if (bufadr == maxcnt) bufadr = 0;
}
if (bufadr == 0) return;
}
ptfill = 0; /* no nulls after first field */
a = atrbuff[bufadr]; /* get attributes for this field */
bufadr++; /* increment buffer address */
if (bufadr == maxcnt) {
bufadr = 0; /* done if wrapped */
return;
}
if (!(a & 0x2000)) return; /* found field if unprotected */
}
}
intra(a1, a2, c, g)
unsigned char a1, a2, c, g;
{
register short endadr;
endadr = cvtadr(a1, a2);
do intdata(c,g); while (endadr != bufadr);
}
inteua(a1, a2)
unsigned char a1, a2;
{
register unsigned char skip, nofmt;
register short endadr, addr, prot;
endadr = cvtadr(a1, a2);
addr = bufadr; /* find previous attribute */
nofmt = 0;
while (!(atrbuff[addr] & 0x8000)) {
if (addr == 0) {
nofmt = 1;
break;
}
else addr--;
}
if (nofmt) prot = 0;
else prot = atrbuff[addr] & 0x2000;
skip = 0;
do {
if (atrbuff[bufadr] & 0x8000) {
prot = atrbuff[bufadr] & 0x2000;
skip = 1;
}
else if (!prot) {
if (skip) {
skip = 0;
}
setnull();
}
else skip = 1;
if (skip) {
bufadr++;
if (bufadr == maxcnt) bufadr = 0;
}
} while (endadr != bufadr);
}
intsfe(field, pairs)
unsigned char * field;
unsigned char pairs;
{
atrbuff[bufadr] = intpairs(0x8000, field, pairs);
chrbuff[bufadr] = 0x1d;
attrloc = bufadr;
bufadr++;
if (bufadr == maxcnt) bufadr = 0;
fmtscrn = 1;
}
intmf(field, pairs)
unsigned char * field;
unsigned char pairs;
{
register short atr;
atr = intpairs(atrbuff[bufadr], field, pairs);
if (atr & 0x8000) {
atrbuff[bufadr] = atr;
chrbuff[bufadr] = 0x1d;
}
bufadr++;
if (bufadr == maxcnt) bufadr = 0;
}
intsa(type, value)
unsigned char type, value;
{
register unsigned char safield[2];
if ((type == 0) && (value == 0)) {
chratr = 0;
return;
}
safield[0] = type;
safield[1] = value;
chratr = intpairs(chratr, safield, 1);
}
intpairs(atr, field, pairs)
unsigned short atr;
unsigned char * field;
unsigned char pairs;
{
register unsigned char c;
register short offset;
offset = 0;
while (pairs > 0) {
c = field[offset+1];
switch(field[offset]) {
case 0xC0: atr &= 0xC0FF;
atr += (c & 0x3f) << 8;
break;
case 0x41: atr &= 0xFFE7;
if (c == 0xF4) c = 0xF3;
atr += (c & 0x03) << 3;
break;
case 0x42: atr &= 0xFFF8;
if ((c & 0x07) == 0) break;
/* if (c == 0) c = 0xF4; */
atr += c & 0x07;
colorfield = 1;
break;
case 0x43: atr &= 0xFF3F;
atr += (c & 0x03) << 6;
break;
default: break;
}
offset += 2;
pairs--;
}
return(atr);
}
intdata(code, geflag)
unsigned char code, geflag;
{
register unsigned char a, f;
chrbuff[bufadr] = code;
atrbuff[bufadr] = chratr;
if ((code == 0xad) || (code == 0xbd))
if (fixbracket) geflag = 1;
if (geflag) atrbuff[bufadr] += 0x4000;
bufadr++;
if (bufadr == maxcnt) bufadr = 0;
}
setnull()
{
chrbuff[bufadr] = 0;
atrbuff[bufadr] = 0;
bufadr++;
if (bufadr == maxcnt) bufadr = 0;
}
cvtadr(a1, a2)
unsigned char a1, a2;
{
short a;
if ((a1 & 0xc0) == 0) /* 14-bit address */
a = (a1 << 8) + a2;
else a = ((a1 & 0x3f) << 6) + (a2 & 0x3f); /* 12-bit address */
if (a < 0) a = 0;
if (a > maxoff) a = maxoff;
return(a);
}
orderinit()
{
register short i, j;
static unsigned char ordercodes[] =
{0x1d, 0x11, 0x13, 0x05, 0x3c, 0x12, 0x08, 0x29, 0x2c, 0x28, 0x00};
for (i=0; i < 256; i++) ordertab[i] = 0xff;
j = strlen(ordercodes);
for (i=0; i < j; i++) ordertab[ordercodes[i]] = 0;
}
setrectsel(offset1, offset2)
short offset1, offset2;
{
short rowmin, rowmax, colmin, colmax, t;
register short row, col;
if (offset1 == offset2) return;
rowmin = offset1 / scrhsize;
colmin = offset1 % scrhsize;
rowmax = offset2 / scrhsize;
colmax = offset2 % scrhsize;
if (rowmin > rowmax) {
t = rowmax;
rowmax = rowmin;
rowmin = t;
}
if (colmin > colmax) {
t = colmax;
colmax = colmin;
colmin = t;
}
for (row = rowmin; row <= rowmax; row++)
for (col = colmin; col <= colmax; col++) {
if (atrbuff[scrhsize*row + col] ^= 0x0020) textsel = 1;
}
invldscr();
}
settextsel(offset1, offset2, invert)
short offset1, offset2;
char invert;
{
short start, end, offset;
start = offset1;
end = offset2;
if (end < start) {
start = offset2;
end = offset1;
}
for (offset = start; offset < end; offset++) {
if (invert) {
atrbuff[offset] ^= 0x0020;
}
else {
atrbuff[offset] |= 0x0020;
}
textsel = 1;
}
invldscr();
}
addfieldsel() /* select entire field for any field partly selected */
{
register short i;
short firstpos, attrpos;
char selflag;
if (!fmtscrn) return;
firstpos = 0;
/* if first byte not an attribute, find attribute for first byte */
if ((atrbuff[0] & 0x8000) == 0) {
firstpos = -1;
for (i = maxoff; i > 0; i--)
if (atrbuff[i] & 0x8000) {
firstpos = i;
break;
}
}
if (firstpos < 0) return;
/* set selection bit for the attribute byte of each field to be selected */
attrpos = firstpos;
for (i=0; i < maxcnt; i++)
if (atrbuff[i] & 0x8000) { /* attribute byte */
attrpos = i;
}
else { /* data byte */
if (atrbuff[i] & 0x0020) atrbuff[attrpos] |= 0x0020;
}
/* set selections bits for all bytes in selected fields */
selflag = (atrbuff[firstpos] & 0x0020) == 0x0020;
for (i=0; i < maxcnt; i++)
if (atrbuff[i] & 0x8000) { /* attribute byte */
selflag = (atrbuff[i] & 0x0020) == 0x0020;
}
else {
if (selflag) atrbuff[i] |= 0x0020;
}
/* reset selection bits in the field attributes */
for (i=0; i < maxcnt; i++)
if (atrbuff[i] & 0x8000) atrbuff[i] &= 0xffdf;
}
resetsel()
{
register short i;
char selflag;
selflag = 0;
for (i = 0; i < maxcnt; i++) {
if (atrbuff[i] & 0x0020) {
selflag = 1;
atrbuff[i] &= 0xffdf;
}
}
textsel = 0;
if (selflag) invldscr();
}
checksel() /* check if there really is selected text */
{
register short i;
textsel = 0;
for (i=0; i < maxcnt; i++) {
if (atrbuff[i] & 0x0020) {
textsel = 1;
return;
}
}
}
addsel(downloc) /* find new starting point for extending text selection */
short * downloc;
{
short startoff, endoff;
register short i;
for (i=0; i < maxcnt; i++) /* get first selection offset */
if (atrbuff[i] & 0x0020) {
startoff = i;
break;
}
for (i=maxoff; i >= 0; i--)
if (atrbuff[i] & 0x0020) {
endoff = i;
break;
}
if ((*downloc) < startoff)
(*downloc) = endoff + 1;
else (*downloc) = startoff;
}
wordadj(loc1, loc2, endadj)
short *loc1, *loc2;
char endadj;
{
short startloc, endloc;
short startline, endline;
char swapped;
swapped = 0;
startloc = *loc1;
endloc = *loc2;
if (startloc > endloc) {
startloc = *loc2;
endloc = *loc1;
swapped = 1;
}
endloc -= endadj;
if (endloc < 0) return;
startline = startloc/scrhsize;
endline = endloc/scrhsize;
while ((!atspace(startloc)) && (startloc > 0) &&
((startloc-1)/scrhsize == startline)) startloc--;
while ((atspace(startloc)) && (startloc < endloc) &&
((startloc+1)/scrhsize <= endline)) startloc++;
while ((!atspace(endloc)) && (endloc < maxoff) &&
((endloc+1)/scrhsize == endline)) endloc++;
while ((atspace(endloc)) && (endloc > startloc) &&
((endloc-1)/scrhsize >= startline)) endloc--;
if (atspace(startloc) && atspace(endloc)) return;
endloc += endadj;
if (swapped) {
*loc2 = startloc;
*loc1 = endloc;
}
else {
*loc1 = startloc;
*loc2 = endloc;
}
}
atspace(loc)
short loc;
{
if (chrbuff[loc] == 0x40) return(1);
if (chrbuff[loc] == 0x00) return(1);
if (atrbuff[loc] & 0x8000) return(1);
return(0);
}